package com.coms514.scheduleme;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

import android.util.Log;

import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.EventReminder;
/** 
* @author Qilin Li
* 
*   RFC 3339
*   http://www.ietf.org/rfc/rfc3339.txt
*   ("start", "2013-10-09T10:00:00.000-05:00");
*   ("end", "2013-10-09T10:25:00.000-05:00");
*   ("colorId", "3");
*   ("description", "Why?How?");
*   
*   RFC2445
*   http://www.ietf.org/rfc/rfc2445
*   RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;
*      BYMINUTE=30
*
*   ("repeating", "RRULE:FREQ=WEEKLY;UNTIL=20131207T102500Z");
*   Freq = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
                / "WEEKLY" / "MONTHLY" / "YEARLY"
* */
public class EventInfo {

	  String id; //EventId
	  String summary; //Event Title
	  String location;
	  String description;
	  String color;
	  Date startDate = new Date("0000-00-00");
	  Date endDate = new Date("0000-00-00");
	  Time startTime = new Time("00:00:00");
	  Time endTime = new Time("00:00:00");
	  
	  String timeZoneNum = "06:00"; //FIXME : timeZone
	  String timeZoneStr = "America/Chicago";
	  boolean allDayEvent = false; //default is false
	  boolean repeating = false;
	  
	 ArrayList<reminder> reminders = new ArrayList<reminder>();
	 RepeatRule repeatRule = new RepeatRule("", "", "");
	 
	  EventInfo() {  
	  }
	  
	  EventInfo(Event event) {
	    update(event);
	  }
	  
	  private class reminder {
		  String method; // "popup", "email", "sms"
		  int minutes;
		  reminder(String method, int minutes) {
			  this.method = method;
			  this.minutes = minutes;
		  }
	  }
	  
	  class RepeatRule {
		  String frequence; 
		  String endDate;
		  String endTime;

		  // endDate: YYYY-MM-DD endTime: HH:MM:SS
		  RepeatRule(String frequence, String endDate, String endTime) {
			  this.frequence = frequence;
			  this.endDate = endDate;
			  this.endTime = endTime;
		  } 
	
		  public void setFrequence(String freq) {
			  frequence = freq;
		  }
		  
		  public String getFrequence() {
			  return frequence;
		  }
		  
		  public void setEndDateTime(String endDate, String endTime) {
			  this.endDate = endDate;
			  this.endTime = endTime;
		  }
		  
		  public void setEndDateTime(int year, int month, int day) {
			  endDate = String.format("%04d-%02d-%02d", year, month, day);
			  endTime = "23:59:00";
		  }
		  
		  // FIXME: "RRULE:FREQ=WEEKLY;UNTIL=20131207T102500Z"
		  public void getRepeatRule(List<String> rpt) {
			  
			  String rptRule = rpt.get(0); //RRULE
			  
			  if (rptRule != null) {
				  StringTokenizer rRule = new StringTokenizer(rptRule, "=" );
				  String str;
			    	if ( rRule.nextToken(":").compareTo("RRULE") == 0) { 
			    		while (rRule.hasMoreTokens()) {
			    			
				    		str = rRule.nextToken("=").substring(1);
				    		
				    		if (str.compareTo("FREQ") == 0) { // FREQ
				    			str = rRule.nextToken(";").substring(1);
				    			frequence = str;
				    			
				    		} else if (str.compareTo("INTERVAL") == 0) { 
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		} else if (str.compareTo("UNTIL") == 0) {
				    			str = rRule.nextToken(";").substring(1);
								String date = str.substring(0, 8);
								String time = str.substring(9, 15);
				    			endDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
								endTime = time.substring(0, 2) + "-" + time.substring(2, 4) + "-" + time.substring(4, 6);
				    		} else if (str.compareTo("BYMONTH") == 0) {
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		} else if (str.compareTo("BYDAY") == 0) {
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		} else if (str.compareTo("BYMONTHDAY") == 0) {
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		} else if (str.compareTo("BYYEARDAY") == 0) {
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		} else {
				    			str = rRule.nextToken(";").substring(1);
				    			
				    		}
			    		}
			    	} else {
			    		// To do 
			    	}
				  
			  } else {
				  Log.v("myTest", "Err: " + "repeating rule is null");
			  } 
		  }
	  }
	  
	// YYYY-MM-DD HH:MM:SS
	  class Date {
		  int year, month, day;
		  String dateString;
		  Date(int year, int month, int day) {
			  setDate(year, month, day);
		  }
		  Date(String str) {
			  setDate(str);
		  }
		  void setDate(int year, int month, int day) {
			  this.year = year;
			  this.month = month;
			  this.day = day;
			  dateString = String.format("%04d-%02d-%02d", year, month, day);
		  }
		  void setDate(String str) {
			  dateString = str.substring(0, 10);
			  year = Integer.parseInt(str.substring(0, 4));
			  month = Integer.parseInt(str.substring(5, 7));
			  day = Integer.parseInt(str.substring(8, 10));
		  }
	  }
	  
	  class Time {
		  int hour, minute;
		  String timeString;
		  Time(int hour, int minute) {
			  setTime(hour, minute);
		  }
		  Time(String str) {
			  setTime(str);
		  }
		  void setTime(int hour, int minute) {
			  this.hour = hour;
			  this.minute = minute;
			  timeString = String.format("%02d:%02d:%02d", hour, minute, 0);
		  }
		  
		  void setTime(String str) {
			  timeString = str;
			  hour = Integer.parseInt(str.substring(0, 2));
			  minute = Integer.parseInt(str.substring(3, 5));
		  }
	  }
  
	  public void addReminder(String method, int minutes) {
		  reminders.add(new reminder(method, minutes));
	  }  
	  
	  /* update local event info */
	  void update(Event event) {
		  String start;  //RFC 3339
		  String end;    //RFC 3339
		  
		  	List<String> repeation;
		  
		    id = event.getId();
		    summary = event.getSummary();
		    location = event.getLocation();
		    description = event.getDescription();
		    color = event.getColorId();
		    
		    /* update date/time infomation of event */
		    EventDateTime dt = event.getStart();
		    if (dt != null) {	    	
			    if (dt.getDate() != null) {
				    if (dt.getDate().isDateOnly() == true) {
				    	allDayEvent = true;
				    	startDate.setDate(dt.getDate().toString());
				    }
			    } else {
			    	if (event.getStart().getDateTime() != null ) {
			    		allDayEvent = false;
					    start = dt.getDateTime().toString();
					    startDate.setDate(start.substring(0, 10));
					    startTime.setTime(start.substring(11, 19));
					    //timeZone = start.substring(24, 29);
			    	}  	
			    }
		    } else {
		    	startDate = null;
		    	startTime = null;
		    }
		    
		    dt = event.getEnd();
		    if (dt != null) {	    	
			    if (dt.getDate() != null) {
				    if (dt.getDate().isDateOnly() == true) {
				    	allDayEvent = true;
				    	endDate.setDate(dt.getDate().toString());
				    }
			    } else {
			    	if (event.getStart().getDateTime() != null ) {
			    		allDayEvent = false;
					    end = dt.getDateTime().toString();
					    endDate.setDate(end.substring(0, 10));
					    endTime.setTime(end.substring(11, 19));
					    //timeZone = start.substring(24, 29);
			    	}  	
			    }
		    } else {
		    	endDate = null;
		    	endTime = null;
		    }
		    
		    
		    // get repeating rule from server
			repeation = event.getRecurrence();
			if (repeation != null) {
				if (repeation.isEmpty()) {
					repeating = false;
				} else {
					repeating = true;
					repeatRule.getRepeatRule(repeation);
				}
			}

			// get reminders from server
			Event.Reminders eventReminders = event.getReminders();
			reminders.clear(); // clear local reminder info
			
			if (eventReminders != null) {
				if (!eventReminders.getUseDefault()) {
					List<EventReminder> reminderList = eventReminders.getOverrides();
					if (eventReminders.getOverrides() != null) {
						for (EventReminder entity : eventReminders.getOverrides()) {
							addReminder(entity.getMethod(), entity.getMinutes());
						}
					}
				}
			}
			

	  }
	
	  //create a Google calendar event instance 
	  Event createEvent() {  	
		    Event event = new Event();
 	        event.setSummary(summary); // event title
 	        event.setLocation(location);  // location
 	        event.setColorId(color);  // color
 	        event.setDescription(description);

 	        // set start date-time, end date-time
		    // FIXME: check date and time format: YYYY-MM-DD, HH:MM:SS
 	        if (allDayEvent == true) {        	
 	        	if(startDate != null) {
 	        		DateTime start = DateTime.parseRfc3339(startDate.dateString);
 	        		event.setStart(new EventDateTime().setDate(start));
 	        	}
 	        	if (endDate != null) {
	 	        	DateTime end = DateTime.parseRfc3339(endDate.dateString);
	 	        	event.setEnd(new EventDateTime().setDate(end));	
 	        	}
 	        } else {
 	        	if(startDate != null) {
 	        		DateTime start = DateTime.parseRfc3339(startDate.dateString + "T" + startTime.timeString + ".000-" + timeZoneNum);
 	        		event.setStart(new EventDateTime().setDateTime(start).setTimeZone(timeZoneStr));
 	        	}
 	        	if (endDate != null) {
		 	        DateTime end = DateTime.parseRfc3339(endDate.dateString + "T" + endTime.timeString + ".000-" + timeZoneNum);
		 	        event.setEnd(new EventDateTime().setDateTime(end).setTimeZone(timeZoneStr));
 	        	}
 	        }

 	        // set repeating rule RRULE:FREQ=WEEKLY;UNTIL=20131207T102500Z
 	        if ((repeating == true) && repeatRule != null) {
 				String until = repeatRule.endDate.substring(0, 4) + repeatRule.endDate.substring(5, 7) + 
 						repeatRule.endDate.substring(8, 10) + "T" + 
 						repeatRule.endTime.substring(0, 2) + repeatRule.endTime.substring(3, 5) + 
 						repeatRule.endTime.substring(6, 8) + "Z";
 				String rRule = "RRULE:FREQ=" + repeatRule.frequence + ";UNTIL=" + until;
 	        	event.setRecurrence(Arrays.asList(rRule));
 	        }
 	        
 	        // set reminders
 	       Event.Reminders eventReminders = new Event.Reminders();
 	       eventReminders.setUseDefault(Boolean.valueOf(false));

 	       ArrayList<EventReminder> reminderArray = new ArrayList<EventReminder>();
 	        for (reminder entity : reminders) {
 	        	EventReminder eventReminder = new EventReminder();
 	        	eventReminder.setMethod(entity.method);
 	        	eventReminder.setMinutes(entity.minutes);
 	        	reminderArray.add(eventReminder);
 	        }
 	        if (reminders.isEmpty() == false) {
	 	        eventReminders.setOverrides(reminderArray);
	 	        event.setReminders(eventReminders);
 	        }
 	        
 	        return event;
	  }	 

}
